#include <stdio.h>  // for printf
#include <string.h> // for memory operation
#include <stdlib.h>
#include <unistd.h> // for sleep
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "lwip/netifapi.h"
#include "lwip/api_shell.h"
#include "lwip/sockets.h"
#include "wifi_sta_connect.h"
//#include <hi_types_base.h>
#include <hi_early_debug.h>
#include "hi_task.h"
#include "pthread.h" //多线程头文件
#include "../oled/include/test.h"

#define CONFIG_WIFI_SSID "XIAO" // 修改为自己的WiFi 热点账号
#define CONFIG_WIFI_PWD "2000122900"   // 修改为自己的WiFi 热点密码

#define TCP_RECV_PORT 5555 // TCP服务器接收端口

const char *qxmsg = "Hello! Received your message. This is qx TCP Server!";
static unsigned int Test; //任务id

/*任务属性的设置*/
const hi_task_attr MonitorTaskAttr_task = {
    .task_prio = 20,          //优先级
    .stack_size = 4096,       //任务分配内存大小
    .task_name = "test_task", //任务名称
};

//线程传入参数结构体
typedef struct
{
    /* data */
    int sfd;
    int client_fd;
    struct sockaddr_in client_addr;
} thread_datastruct;

thread_datastruct thread1_data;

void *thread1_client1(thread_datastruct *client_data);
/*任务执行函数，启动TCP服务器端*/
static int tcp_server_task()
{
    struct sockaddr_in srv_addr = {0};
    struct sockaddr_in client_addr = {0};
    int ret = 0;
    unsigned int opt = 1;

    // 连接wifi
    WifiConnect(CONFIG_WIFI_SSID, CONFIG_WIFI_PWD);
    sleep(2);

    // 创建socket
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sfd == -1)
    {
        printf("tcp_server_task: create socket failed!\r\n");
        return -1;
    }
    else
    {
        printf("tcp_server_task: create socket success!\r\n");
    }

    // 绑定端口
    srv_addr.sin_family = AF_INET;
    srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    srv_addr.sin_port = htons(TCP_RECV_PORT);
    ret = bind(sfd, (struct sockaddr *)&srv_addr, sizeof(srv_addr));
    if (ret != 0)
    {
        printf("tcp_server_task:bind failed, error is %d\r\n", errno);
        closesocket(sfd);
        return -1;
    }
    else
    {
        printf("tcp_server_task: bind success!\r\n");
    }

    ret = listen(sfd, 20); //监听的客户端端口数量为20
    if (ret != 0)
    {
        printf("tcp_server_task:listen failed,return is %d\r\n", ret);
        closesocket(sfd);
        sfd = -1;
        return -1;
    }
    else
    {
        printf("tcp_server_task:listen success!\r\n");
    }

    // 循环处理各客户端数据请求
    int sin_size = sizeof(struct sockaddr_in);
    int client_fd;

    pthread_t pthread1;

    while (1)
    {
        if ((client_fd = accept(sfd, (struct sockaddr_in *)&client_addr, (socklen_t *)&sin_size)) == -1)
        {
            printf("tcp_server_task:accept failed\r\n");
            continue;
        }
        printf("tcp_server_task:accept client addr:%s\r\n", inet_ntoa(client_addr.sin_addr));


        thread1_data.client_fd = client_fd;
        thread1_data.sfd = sfd;
        thread1_data.client_addr = client_addr;


        ret = pthread_create(&pthread1, NULL, thread1_client1, &thread1_data);
        
        if (ret != 0)
        {
            printf("pthread create error!\r\n");
        }
        else
        {
            printf("pthread create success!\r\n");
        }
    }

    closesocket(sfd);

    return 0;
}

extern key_val;

void *thread1_client1(thread_datastruct *client_data)
{
    char recvbuf[512] = {0};
    int sin_size = sizeof(struct sockaddr_in);
    int client_fd = client_data->client_fd;
    int sfd = client_data->sfd;
    struct sockaddr_in client_addr = client_data->client_addr;
    //处理目标
    ssize_t ret = 0;
    while (1)
    {
        /* code */
        if ((ret = recv(client_fd, recvbuf, sizeof(recvbuf), 0)) == -1)
        {
            printf("tcp_server_task:recv failed\r\n");
        }
        else
        {
            printf("recv1 :%s\r\n", recvbuf);
            key_val=recvbuf[0];
        }

        if (ret = send(client_fd, qxmsg, strlen(qxmsg), 0) == -1)
        {
            printf("tcp_server_task:send failed\r\n");
        }
        else
        {
            printf("send1 :%s\r\n", qxmsg);
        }
    }
}

hi_void tcp_server_demo(hi_void)
{
    int ret;
    ret = hi_task_create(&Test, //任务id
                         &MonitorTaskAttr_task,
                         tcp_server_task, //任务处理函数//
                         NULL);           //任务处理函数参数

    if (ret < 0)
    {
        printf("Create tcp server task failed [%d]\r\n", ret);
        return;
    }
}

APP_FEATURE_INIT(tcp_server_demo);
